package ch.mustaffah.aoide.gui;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.BoxLayout;
import javax.swing.JPanel;

import ch.mustaffah.aoide.model.Flat;
import ch.mustaffah.aoide.model.Score;
import ch.mustaffah.aoide.model.ScoreContainer;
import ch.mustaffah.aoide.model.ScorePattern;
import ch.mustaffah.aoide.util.Translator;

public class AoideKeyBord extends JPanel implements View {
	/**
	 * 
	 */

	private static final long serialVersionUID = 1L;
	private AoideKeyBordPanel aoideKeyBordPanel;
	private AoideScoreDisplayPanel aoideScoreDisplayPanel;
	private AoideConfigurationPanel aoideConfigurationPanel;

	public AoideKeyBord() {
		initializeView();
		addActionListeners();
	}

	private AoideKeyBordPanel getAoideKeyBordPanel() {
		if (this.aoideKeyBordPanel == null) {
			this.aoideKeyBordPanel = new AoideKeyBordPanel();
		}
		return this.aoideKeyBordPanel;
	}

	private AoideScoreDisplayPanel getScoreDisplay() {
		if (this.aoideScoreDisplayPanel == null) {
			this.aoideScoreDisplayPanel = new AoideScoreDisplayPanel();
		}
		return this.aoideScoreDisplayPanel;
	}
	
	public TimeMode getTimeSelection(){
		return (TimeMode)this.getConfigurationPanel().getTimeSelection().getSelectedItem();
	}

	public void initializeView() {
		AoideConfigurationPanel configurationPanel = getConfigurationPanel();
		JPanel container = new JPanel();
		container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
		container.add(getAoideKeyBordPanel());
		this.setLayout(new BorderLayout());
		this.add(configurationPanel, BorderLayout.NORTH);
		this.add(container, BorderLayout.CENTER);
		this.add(getScoreDisplay(), BorderLayout.SOUTH);
		this.setVisible(true);
	}

	private AoideConfigurationPanel getConfigurationPanel() {
		if(this.aoideConfigurationPanel==null){
			this.aoideConfigurationPanel=new AoideConfigurationPanel();
		}
		return this.aoideConfigurationPanel;
	}

	public ArrayList<String> getSelectedScores() {
		boolean[] selection1 = getAoideKeyBordPanel().getSelectionPattern(1);
		boolean[] selection2 = getAoideKeyBordPanel().getSelectionPattern(2);
		boolean[] selection3 = getAoideKeyBordPanel().getSelectionPattern(3);
		boolean[] selection4 = getAoideKeyBordPanel().getSelectionPattern(4);
		boolean[] selection5 = getAoideKeyBordPanel().getSelectionPattern(5);
		boolean[] selection6 = getAoideKeyBordPanel().getSelectionPattern(6);
		boolean[] selection7 = getAoideKeyBordPanel().getSelectionPattern(7);
		boolean[] selection8 = getAoideKeyBordPanel().getSelectionPattern(8);

		ScoreContainer container1 = createScoreContainerFromSelectionArray(selection1);
		ScoreContainer container2 = createScoreContainerFromSelectionArray(selection2);
		ScoreContainer container3 = createScoreContainerFromSelectionArray(selection3);
		ScoreContainer container4 = createScoreContainerFromSelectionArray(selection4);
		ScoreContainer container5 = createScoreContainerFromSelectionArray(selection5);
		ScoreContainer container6 = createScoreContainerFromSelectionArray(selection6);
		ScoreContainer container7 = createScoreContainerFromSelectionArray(selection7);
		ScoreContainer container8 = createScoreContainerFromSelectionArray(selection8);

		container1.setOctave(1);
		container2.setOctave(2);
		container3.setOctave(3);
		container4.setOctave(4);
		container5.setOctave(5);
		container6.setOctave(6);
		container7.setOctave(7);
		container8.setOctave(8);

		ArrayList<String> selectedScores = new ArrayList<String>();
		selectedScores.addAll(Translator.getSelectedScores(container1, Flat.F));
		selectedScores.addAll(Translator.getSelectedScores(container2, Flat.F));
		selectedScores.addAll(Translator.getSelectedScores(container3, Flat.F));
		selectedScores.addAll(Translator.getSelectedScores(container4, Flat.F));
		selectedScores.addAll(Translator.getSelectedScores(container5, Flat.F));
		selectedScores.addAll(Translator.getSelectedScores(container6, Flat.F));
		selectedScores.addAll(Translator.getSelectedScores(container7, Flat.F));
		selectedScores.addAll(Translator.getSelectedScores(container8, Flat.F));
		return selectedScores;
	}

	private ScoreContainer createScoreContainerFromSelectionArray(
			boolean[] selection) {
		ScoreContainer container = new ScoreContainer();
		Score[] scoresArray = new Score[] { new Score(0, 1, selection[0]),
				new Score(0, 1, selection[1]), new Score(0, 1, selection[2]),
				new Score(0, 1, selection[3]), new Score(0, 1, selection[4]),
				new Score(0, 1, selection[5]), new Score(0, 1, selection[6]),
				new Score(0, 1, selection[7]), new Score(0, 1, selection[8]),
				new Score(0, 1, selection[9]), new Score(0, 1, selection[10]),
				new Score(0, 1, selection[11]) };
		ScorePattern pattern = new ScorePattern(scoresArray);
		container.applyScorePattern(pattern);
		return container;
	}

	public void clearAllSelected() {
		getAoideKeyBordPanel().selectAll(false);
	}

	private void setRandomSelectionPattern() {
		getAoideKeyBordPanel().setSelectionPattern(Translator.createSelectionPattern());
	}

	private String createMusicStringFromSelectionArray(
			ArrayList<String> selectedScores, int transpose, int playtimes,
			PlayMode mode, ArrayList<TimeMode> timePattern, Instruments instrument) {
		String scaleResult = "";
		for (int i = 0; i < playtimes; i++) {
			if (mode.equals(PlayMode.RANDOM)) {
				scaleResult = Translator.translateToRandomJFugueString(
						selectedScores, timePattern, instrument);
			} else if (mode.equals(PlayMode.SCALE)) {
				scaleResult = Translator
						.translateToJFugueString(selectedScores, TimeMode.i, instrument);
			}
			this.aoideScoreDisplayPanel.getDisplayBox().setText(scaleResult);
		}
		return scaleResult;
	}

	public String getCurrentMusicString(int phraseLengthInThirtyTwos, boolean randomTimePatternMode, TimeMode timeMode) {
		// create music from selection
		PlayMode mode = (PlayMode) this.getConfigurationPanel()
				.getModeSelection().getSelectedItem();
		ArrayList<String> selectedScores = this.getSelectedScores();
		ArrayList<TimeMode> timePattern;
		if(randomTimePatternMode){
			timePattern=Translator.getRandomRhythmPattern(phraseLengthInThirtyTwos);
		}else{
			timePattern=Translator.getRhythmPattern(timeMode);
		}
		Instruments instrument=(Instruments)this.getConfigurationPanel().getInstrumentSelection().getSelectedItem();
		String musicString = createMusicStringFromSelectionArray(
				selectedScores, 0, 1, mode, timePattern, instrument);
		// write music to textfield
		aoideScoreDisplayPanel.getDisplayBox().setText(musicString);
		return musicString;
	}

	private void addActionListeners() {
		this.getConfigurationPanel().getClearButton().addActionListener(
				new ActionListener() {
					public void actionPerformed(ActionEvent arg0) {
						clearAllSelected();
					}
				});
		this.getConfigurationPanel().getRandomPatternButton().addActionListener(
				new ActionListener() {
					public void actionPerformed(ActionEvent arg0) {
						setRandomSelectionPattern();
					}
				});
		
	}

}
